package me.zhengjie.modules.quartz.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qiaofang.applet.constants.UpDownFlagConstants;
import com.qiaofang.applet.service.other.domain.CityCompany;
import com.qiaofang.applet.service.other.domain.Corporation;
import com.qiaofang.applet.service.other.domain.FirsthandRules;
import com.qiaofang.applet.service.other.domain.PropertyRules;
import com.qiaofang.applet.service.other.service.CityCompanyService;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.applet.service.property.service.FirsthandEstateService;
import com.qiaofang.applet.service.property.service.PropertyService;
import com.qiaofang.common.request.DataRequest;
import com.qiaofang.common.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.quartz.service.constants.SyncConstants;
import me.zhengjie.modules.quartz.service.dto.SyncCommon;
import me.zhengjie.modules.sync.request.FirsthandRulesDTO;
import me.zhengjie.modules.sync.request.PropertyRulesDTO;
import me.zhengjie.modules.sync.request.UpDownProcessingRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Slf4j
@Component
public class UpDownStateBrushTask {

    private static final String FIRSTHAND_UP_DOWN_API = "/api/dataprocessing/upDownProcessing/estateUuidList";

    private static final String PROPERTY_UP_DOWN_API = "/api/dataprocessing/upDownProcessing/propertyUuidList";

    @Autowired
    private CorporationService corporationService;

    @Autowired
    private CityCompanyService cityCompanyService;

    @Autowired
    private PropertyService propertyService;

    @Autowired
    private FirsthandEstateService firsthandEstateService;

    @Autowired
    private MongoTemplate mongoTemplate;

    private RestTemplate template;

    {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(30000);
        requestFactory.setReadTimeout(30000);
        template = new RestTemplate(requestFactory);
    }


    public void run() {
        log.info("UpDownStateBrushTask run start");
        Corporation corporation = new Corporation();
        corporation.setDeleted(Boolean.FALSE);
        corporation.setV20Flag(Boolean.FALSE);
        Iterable<Corporation> list = corporationService.findAll(Example.of(corporation));
        list.forEach(item -> {
            String corporationCode = item.getCorporationCode();
            log.info("开始处理集团:{}的上下架状态，开始时间:{}", corporationCode, new Date());
            long currentTimeMillis = System.currentTimeMillis();

            PropertyRules propertyRules = item.getPropertyRules();
            FirsthandRules firsthandRules = item.getFirsthandRules();

            long num = propertyService.batchDownProperty(propertyRules, corporationCode, currentTimeMillis);
            log.info("集团:{}批量下架二手房数量:{}", corporationCode, num);
            num = firsthandEstateService.batchDownFirsthand(firsthandRules, corporationCode, currentTimeMillis);
            log.info("集团:{}批量下架新房数量:{}", corporationCode, num);

            //未配置上下架数据处理域名
            if (StringUtil.isEmpty(item.getPullDomain())) {
                log.error("集团:{} 的上下架数据处理域名未配置", corporationCode);
                return;
            }

            FirsthandRulesDTO firsthandRulesDTO = new FirsthandRulesDTO();
            BeanUtils.copyProperties(firsthandRules, firsthandRulesDTO);
            PropertyRulesDTO propertyRulesDTO = new PropertyRulesDTO();
            BeanUtils.copyProperties(propertyRules, propertyRulesDTO);

            Criteria criteria = Criteria.where("corporationCode").is(corporationCode).and("status").is(1);
            List<CityCompany> companies = mongoTemplate.find(new Query(criteria), CityCompany.class);
            companies.forEach(company -> {
                String companyUuid = company.getCompanyUuid();
                SyncCommon syncCommon = new SyncCommon();
                syncCommon.setCorporationCode(item.getCorporationCode());
                syncCommon.setAppId(item.getPullAppId());
                syncCommon.setAppKey(item.getPullAppKey());
                syncCommon.setDomain(item.getPullDomain());
                //具体公司信息
                syncCommon.setCityCode(company.getCityCode());
                syncCommon.setCompanyUuid(company.getCompanyUuid());

                log.info("开始处理公司:{}的上下架状态，开始时间:{}", company.getCompanyUuid(), new Date());

                List<String> propertyUuidList = propertyService.getUndisposedUuidList(companyUuid, currentTimeMillis);
                log.info("公司:{},未处理二手房源数量:{}", company.getCompanyUuid(), propertyUuidList.size());
                List<String> estateUuidList = firsthandEstateService.getUndisposedUuidList(companyUuid, currentTimeMillis);
                log.info("公司:{},未处理新房楼盘数量:{}", company.getCompanyUuid(), estateUuidList.size());

                upDownPropertyProcessing(syncCommon, propertyUuidList, propertyRulesDTO);
                upDownFirsthandProcessing(syncCommon, estateUuidList, firsthandRulesDTO);
            });

            log.info("完成处理集团:{}的上下架状态，完成时间:{}", corporationCode, new Date());
        });
        log.info("UpDownStateBrushTask run end");
    }

    private void upDownPropertyProcessing(SyncCommon syncCommon, List<String> propertyUuidList, PropertyRulesDTO propertyRulesDTO) {
        long num;
        if (!propertyRulesDTO.isValidParam()) {
            //不需要调用微服务，全部上架
            num = propertyService.batchProcessingByUuidList(propertyUuidList, syncCommon.getCompanyUuid(), UpDownFlagConstants.UP_FLAG.getValue());
            log.info("公司:{}批量上架二手房源数量:{}(未调用微服务)", syncCommon.getCompanyUuid(), num);
            propertyUuidList = null;
        }
        if (!CollectionUtils.isEmpty(propertyUuidList)) {
            List<String> upPropertyUuidList = new LinkedList<>();
            List<List<String>> partition = Lists.partition(propertyUuidList, 1800);
            UpDownProcessingRequest upDownProcessingRequest = new UpDownProcessingRequest();
            upDownProcessingRequest.setPropertyRules(propertyRulesDTO);
            for (List<String> uuidList : partition) {
                upDownProcessingRequest.setUuidList(uuidList);
                List<String> list = httpRequestData(upDownProcessingRequest, syncCommon, PROPERTY_UP_DOWN_API);
                if (list == null){
                    log.error("处理公司:{} 的二手房源上下架,调用微服务失败", syncCommon.getCompanyUuid());
                    return;
                }
                upPropertyUuidList.addAll(list);
            }
            propertyUuidList.removeAll(upPropertyUuidList);
            num = propertyService.batchProcessingByUuidList(upPropertyUuidList, syncCommon.getCompanyUuid(), UpDownFlagConstants.UP_FLAG.getValue());
            log.info("公司:{}批量上架二手房源数量:{}", syncCommon.getCompanyUuid(), num);
            num = propertyService.batchProcessingByUuidList(propertyUuidList, syncCommon.getCompanyUuid(), UpDownFlagConstants.DOWN_FLAG.getValue());
            log.info("公司:{}批量下架二手房源数量:{}", syncCommon.getCompanyUuid(), num);
        }
    }


    private void upDownFirsthandProcessing(SyncCommon syncCommon, List<String> estateUuidList, FirsthandRulesDTO firsthandRulesDTO) {
        long num;
        if (!firsthandRulesDTO.isValidParam()) {
            //不需要调用微服务，全部上架
            num = firsthandEstateService.batchProcessingByUuidList(estateUuidList, syncCommon.getCompanyUuid(), UpDownFlagConstants.UP_FLAG.getValue());
            log.info("公司:{}批量上架新房楼盘数量:{}(未调用微服务)", syncCommon.getCompanyUuid(), num);
            estateUuidList = null;
        }
        if (!CollectionUtils.isEmpty(estateUuidList)) {
            List<String> upEstateUuidList = new LinkedList<>();
            List<List<String>> partition = Lists.partition(estateUuidList, 18000);
            UpDownProcessingRequest upDownProcessingRequest = new UpDownProcessingRequest();
            upDownProcessingRequest.setFirsthandRules(firsthandRulesDTO);
            for (List<String> uuidList : partition) {
                upDownProcessingRequest.setUuidList(uuidList);
                List<String> list = httpRequestData(upDownProcessingRequest, syncCommon, FIRSTHAND_UP_DOWN_API);
                if (list == null){
                    log.error("处理公司:{} 的新房楼盘上下架,调用微服务失败", syncCommon.getCompanyUuid());
                    return;
                }
                upEstateUuidList.addAll(list);
            }
            estateUuidList.removeAll(upEstateUuidList);
            num = firsthandEstateService.batchProcessingByUuidList(upEstateUuidList, syncCommon.getCompanyUuid(), UpDownFlagConstants.UP_FLAG.getValue());
            log.info("公司:{}批量上架新房楼盘数量:{}", syncCommon.getCompanyUuid(), num);
            num = firsthandEstateService.batchProcessingByUuidList(estateUuidList, syncCommon.getCompanyUuid(), UpDownFlagConstants.DOWN_FLAG.getValue());
            log.info("公司:{}批量下架新房楼盘数量:{}", syncCommon.getCompanyUuid(), num);
        }
    }

    private HttpHeaders getHeaders(SyncCommon syncCommon) {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        headers.add("X-AUTH-APP-ID", syncCommon.getAppId());
        headers.add("X-AUTH-KEY", syncCommon.getAppKey());
        headers.add("companyUuid", syncCommon.getCompanyUuid());
        log.info("========>headers:{}", JSON.toJSONString(headers));
        return headers;
    }

    private List<String> httpRequestData(UpDownProcessingRequest bodys, SyncCommon syncCommon, String apiUrl) {
        HttpHeaders headers = getHeaders(syncCommon);
        DataRequest dataRequest = new DataRequest();
        dataRequest.setParam(bodys);
        String url = syncCommon.getDomain() + apiUrl;
        String result = null;
        log.info("sync params {},header {}", dataRequest, headers);
        try {
            result = template.postForObject(url, new HttpEntity<>(dataRequest, headers), String.class);
            log.info("sync result {}", result);
        } catch (Exception e) {
            log.error("httpRequest error", e);
        }

        if (Objects.isNull(result)) {
            return null;
        }
        JSONObject resultObject = JSON.parseObject(result);
        if (null == resultObject) {
            return null;
        }
        String responseCode = resultObject.getString("responseCode");
        if (!SyncConstants.ON.equals(responseCode)) {
            String responseMessage = resultObject.getString("responseMessage");
            log.info("sync error {}", responseMessage);
            return null;
        }
        if (Objects.isNull(resultObject)) {
            return null;
        }
        JSONArray data = resultObject.getJSONArray("data");
        return data.toJavaList(String.class);
    }
}
